package com.qf.electronic.aspect;

import com.qf.electronic.pojo.Log;
import com.qf.electronic.pojo.User;
import com.qf.electronic.service.ILogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;

@Aspect
@Component
//@Slf4j
public class LogAspect {

    @Autowired
    private ILogService logService;

    //这个是操作日志的切点
    @Pointcut("execution(* com.qf.electronic.controller..*(..))")
    public void pointcut1(){}


    //这个是业务日志的切点
    @Pointcut("execution(* com.qf.electronic.service..*(..))")
    public void pointcut2(){}

    @Around("pointcut1()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        Operation operation = method.getAnnotation(Operation.class);
        if(operation != null){
            String operationName =  operation.value();
            Object[] args = pjp.getArgs();
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            User user = (User) authentication.getPrincipal();
            String username = user.getUsername();
            String name = user.getName();
            String parameterInfo = Arrays.toString(args);
            Log log = new Log();
            log.setOperation(operationName);
            log.setOperationTime(LocalDateTime.now());
            log.setParams(parameterInfo);
            log.setUser(username);
            log.setOperatorName(name);
            try {
                Object result = pjp.proceed();
//                log.info("{}进行了{},执行参数：{}", username, operationName, parameterInfo);
                logService.save(log);
                return result;
            } catch (Throwable t) {
                log.setError(1);
                logService.save(log);
//                log.error("{}进行了{},执行参数：{}，执行时发生了异常：{}", username, operationName, parameterInfo, t.getMessage());
                throw t;
            }
        }
        return pjp.proceed();
    }
}
